<template>
    <canvasArea ref="canvasRef"></canvasArea>
     <button @click="handleUndo">撤销</button>
     <button @click="handleClear">清空</button>
</template>
<script lang="ts" setup>
import canvasArea from './canvasArea.vue'
const canvasRef = ref()

const handleUndo = () => {
    canvasRef.value?.undo()
}
const handleClear = () => {
    canvasRef.value?.clearCanvas()
}



const centerScaleImageData = (
    sourceData: ImageData,
    scaleFactor: number
): ImageData => {
    // 计算目标尺寸（保持整数尺寸）
    const targetWidth = Math.floor(sourceData.width * scaleFactor)
    const targetHeight = Math.floor(sourceData.height * scaleFactor)

    // 创建离屏 Canvas
    const sourceCanvas = new OffscreenCanvas(sourceData.width, sourceData.height)
    const sourceCtx = sourceCanvas.getContext('2d', { willReadFrequently: true })!
    sourceCtx.putImageData(sourceData, 0, 0)

    // 创建目标 Canvas
    const targetCanvas = new OffscreenCanvas(targetWidth, targetHeight)
    const targetCtx = targetCanvas.getContext('2d', { alpha: true })!
    
    // 计算源图像裁剪区域（保持中心点）
    const sourceRatio = sourceData.width / sourceData.height
    const targetRatio = targetWidth / targetHeight
    
    let sx = 0, sy = 0, sw = sourceData.width, sh = sourceData.height
    
    // 根据比例差异调整源区域
    if (sourceRatio > targetRatio) {
        sw = sourceData.height * targetRatio
        sx = (sourceData.width - sw) / 2
    } else {
        sh = sourceData.width / targetRatio
        sy = (sourceData.height - sh) / 2
    }

    // 高质量缩放绘制
    targetCtx.imageSmoothingQuality = 'high'
    targetCtx.drawImage(
        sourceCanvas,
        sx, sy, sw, sh, // 源图像裁剪区域
        0, 0, targetWidth, targetHeight // 目标绘制区域
    )
    
    return targetCtx.getImageData(0, 0, targetWidth, targetHeight)
}

// 本来想通过绘画的图案 生成n*n的亮起的格子，但是这个效果与预期差别太大了，所以就弃用了
const detectColorGrid = (gridSize: number = 8, imageData: ImageData, w: number, h: number) => {
    if (gridSize <= 0 || !imageData) return []
    
    // 优化1：动态计算缩放比例
    const minCellPixels = 20 // 每个网格最少采样像素
    const scaleFactor = Math.min(
        1,
        (gridSize * minCellPixels) / Math.max(w, h)
    )

    // 优化2：添加边缘保护缩放
    const paddedData = padImageData(imageData, 2) // 添加2像素边缘
    const scaledData = centerScaleImageData(paddedData, scaleFactor)
    
    // 优化3：动态计算阈值
    const alphaValues = scaledData.data.filter((_,i) => i % 4 === 3)
    const avgAlpha = alphaValues.reduce((a,b) => a+b,0) / alphaValues.length
    const dynamicThreshold = Math.max(20, avgAlpha * 0.3)

    // 优化4：改进采样策略
    const gridState: string[] = []
    const cellWidth = scaledData.width / gridSize
    const cellHeight = scaledData.height / gridSize

    for (let y = 0; y < gridSize; y++) {
        for (let x = 0; x < gridSize; x++) {
            // 生成动态采样网格
            const samplePoints = generateSamplePoints(x, y, cellWidth, cellHeight)
            
            // 计算加权透明度
            let totalAlpha = 0
            samplePoints.forEach(({x: px, y: py, weight}) => {
                const idx = (Math.floor(py) * scaledData.width + Math.floor(px)) * 4 + 3
                totalAlpha += scaledData.data[idx] * weight
            })
            
            gridState[y * gridSize + x] = totalAlpha > dynamicThreshold ? 'active' : ""
        }
    }

    return gridState
}

// 新增辅助方法
const padImageData = (data: ImageData, padding: number): ImageData => {
    const canvas = new OffscreenCanvas(data.width + padding*2, data.height + padding*2)
    const ctx = canvas.getContext('2d')!
    ctx.fillStyle = 'rgba(0,0,0,0)'
    ctx.fillRect(0, 0, canvas.width, canvas.height)
    ctx.putImageData(data, padding, padding)
    return ctx.getImageData(0, 0, canvas.width, canvas.height)
}

const generateSamplePoints = (x: number, y: number, w: number, h: number) => {
    const points = []
    // 3x3 网格采样 + 中心加强
    for (let dy = 0.2; dy <= 0.8; dy += 0.3) {
        for (let dx = 0.2; dx <= 0.8; dx += 0.3) {
            const weight = dx === 0.5 && dy === 0.5 ? 1.5 : 1 // 中心点权重更高
            points.push({
                x: (x + dx) * w,
                y: (y + dy) * h,
                weight
            })
        }
    }
    return points
}

defineExpose({
    exportCanvas: () => {
        return canvasRef.value
    }
})
</script>